using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.Win32;

namespace VisualStudioMruFileUtil
{
	internal class MruManager
	{
		private string[] keyNames = new string[50];
		private VisualStudioVersion vsVersion;

		public MruManager(VisualStudioVersion vsVersion)
		{
			InitKeyNames();
			this.vsVersion = vsVersion;
		}

		private void InitKeyNames()
		{
			for ( int i = 0; i < keyNames.Length; i++ )
			{
				keyNames[i] = "file" + (i + 1);
			}
		}

		public List<string> GetRecentFiles()
		{
			RegistryKey key = Registry.CurrentUser.OpenSubKey( vsVersion.KeyName, false );
			if ( key == null )
			{
				return new List<string>();
			}

			using ( key )
			{
				List<string> fileList = new List<string>();

				foreach ( string keyName in keyNames )
				{
					string file = key.GetValue( keyName ) as string;
					if ( !string.IsNullOrEmpty( file ) )
					{
						file = file.Trim();
						file = TrimProjectGuidFromProjectTargetFiles(file);
					   file = RemoveTrailingBoolean(file);
						fileList.Add( file );
					}
				}

				return fileList;
			}
		}

		private string TrimProjectGuidFromProjectTargetFiles(string file)
		{
			int index = file.LastIndexOf("|{");
			bool endsWithBrace = file.EndsWith("}");
			if (index < 0 || !endsWithBrace)
			{
				return file;
			}

			return file.Substring(0, index);
		}

      private string RemoveTrailingBoolean(string file)
      {
         // e.g. D:\My Files\Programmi...FileUtil\VisualStudioMruFileUtil.sln||False
         int index = file.IndexOf("|");
         if (index < 0)
            return file;

         return file.Substring(0, index);
      }

		internal void ClearAll()
		{
			RegistryKey key = Registry.CurrentUser.OpenSubKey( vsVersion.KeyName, true );
			if ( key == null )
			{
				return;
			}

			using ( key )
			{
				for ( int i = 0; i < keyNames.Length; i++ )
				{
					key.DeleteValue( keyNames[i], false );
				}
			}
		}

		internal void ClearMissing()
		{
			List<string> fileList = GetRecentFiles();

			RegistryKey key = Registry.CurrentUser.OpenSubKey( vsVersion.KeyName, true );
			if ( key == null )
			{
				return;
			}

			List<string> existingFiles = new List<string>();

			using ( key )
			{
				foreach ( string file in fileList )
				{
					if ( File.Exists( file ) )
					{
						existingFiles.Add( file );
					}
				}

				for ( int i = 0; i < keyNames.Length; i++ )
				{
					if ( i < existingFiles.Count )
					{
						key.SetValue( keyNames[i], existingFiles[i] );
					}
					else
					{
						key.DeleteValue( keyNames[i], false );
					}
				}
			}
		}

		internal bool HasMissingFiles
		{
			get
			{
				List<string> fileList = GetRecentFiles();
				foreach ( string file in fileList )
				{
					if ( !File.Exists( file ) )
					{
						return true;
					}
				}

				return false;
			}
		}

      public bool HasCsProjFiles
      {
         get
         {
            foreach (string file in this.GetRecentFiles())
            {
               if (file.ToLower().EndsWith(".csproj") ||
                  file.ToLower().EndsWith(".vbproj"))
               {
                  return true;
               }
            }
            return false;
         }
      }
 
		public VisualStudioVersion VsVersion
		{
			get { return vsVersion; }
		}

		public override string ToString()
		{
			return VsVersion.DisplayName;
		}

		internal void ClearFiles(string[] files)
		{
			List<string> fileList = GetRecentFiles();

			RegistryKey key = Registry.CurrentUser.OpenSubKey( vsVersion.KeyName, true );
			if ( key == null )
			{
				return;
			}

			List<string> savedFiles = new List<string>();
			List<string> clearedFiles = new List<string>( files );

			using ( key )
			{
				foreach ( string file in fileList )
				{
					if ( !clearedFiles.Contains( file ) )
					{
						savedFiles.Add( file );
					}
				}

				for ( int i = 0; i < keyNames.Length; i++ )
				{
					if ( i < savedFiles.Count )
					{
						key.SetValue( keyNames[i], savedFiles[i] );
					}
					else
					{
						key.DeleteValue( keyNames[i], false );
					}
				}
			}
		}
	}
}